/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package iqq.ui;

import iqq.service.GroupService;
import iqq.service.CategoryService;
import iqq.service.StackMessageService;
import iqq.service.MessageService;
import iqq.service.MemberService;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
import javax.swing.tree.*;
import iqq.comm.Auth;
import iqq.comm.IconTreeNode;
import iqq.comm.MyDefaultTreeCellRenderer;
import iqq.model.Category;
import iqq.model.Group;
import iqq.model.Member;
import iqq.model.Message;
import iqq.util.BrowserUtil;
import iqq.util.ErrorMessage;
import iqq.util.Log;
import iqq.util.ThreadUtil;

/**
 *
 * @author chenzhihui
 */
public class MainPanel extends javax.swing.JPanel {
    
    private MainFrame mainFrame = MainFrame.getMainFrame();
    private Map map = mainFrame.getMap();
    private NewMessageFrame newMessageFrame = null;
    private Member member = null;
    private List<Category> categoryList = null;
    private Map messagePrompt = new HashMap();
    private boolean isNewMessage;
    private JTree contactsTree = null;
    private DefaultTreeModel treeModel = null;
    private FloatInfoDialog floatInfo = null;
    private JTree groupTree = null;
    private JTree recentTree = null;

    /**
     * Creates new form MainPanel
     */
    public MainPanel() {
        //ResourceBundle bundle = ResourceBundle.getBundle("iqq/res/res"); // NOI18N
        //MainFrame.getMainFrame().setIBackground(bundle.getString("iqq.mainBg"));
        MainFrame.getMainFrame().setIBackground(null);
        initComponents();
        mainFrame.setIconImage(Auth.getMember().getFace().getImage());
        Log.println("mainPanel");
        this.setVisible(true);

        //设置托盘
        try {
            TrayFactory.getInstance().createTray(mainFrame, Auth.getMember().getFace(), "Hello，" + Auth.getMember().getNickname() + "!");
        } catch (Exception ex) {
            Logger.getLogger(MainPanel.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        dialogMemberInfo = new javax.swing.JDialog();
        btnFace = new javax.swing.JButton();
        textNickname = new javax.swing.JTextField();
        labLevel = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        textLnick = new javax.swing.JTextField();
        jTabbedPane2 = new javax.swing.JTabbedPane();
        jPanel1 = new javax.swing.JPanel();
        jLabel5 = new javax.swing.JLabel();
        jLabel6 = new javax.swing.JLabel();
        jLabel7 = new javax.swing.JLabel();
        jLabel8 = new javax.swing.JLabel();
        comboGender = new javax.swing.JComboBox();
        comboChineseZodiac = new javax.swing.JComboBox();
        comboBlood = new javax.swing.JComboBox();
        comboConstel = new javax.swing.JComboBox();
        jLabel9 = new javax.swing.JLabel();
        jLabel10 = new javax.swing.JLabel();
        jLabel11 = new javax.swing.JLabel();
        dateChooserBirthday = new iqq.ui.DateChooser();
        textMobile = new javax.swing.JTextField();
        textPhone = new javax.swing.JTextField();
        jLabel12 = new javax.swing.JLabel();
        textCountry = new javax.swing.JTextField();
        jLabel13 = new javax.swing.JLabel();
        textCity = new javax.swing.JTextField();
        jLabel14 = new javax.swing.JLabel();
        textProvince = new javax.swing.JTextField();
        jLabel15 = new javax.swing.JLabel();
        textEmail = new javax.swing.JTextField();
        jLabel16 = new javax.swing.JLabel();
        textOccupation = new javax.swing.JTextField();
        jLabel17 = new javax.swing.JLabel();
        textCollege = new javax.swing.JTextField();
        jLabel18 = new javax.swing.JLabel();
        textHomepage = new javax.swing.JTextField();
        jLabel19 = new javax.swing.JLabel();
        jScrollPane3 = new javax.swing.JScrollPane();
        textPersonal = new javax.swing.JTextArea();
        jButton9 = new javax.swing.JButton();
        jButton10 = new javax.swing.JButton();
        jLabel20 = new javax.swing.JLabel();
        topPanel = new javax.swing.JPanel();
        QQToolBar = new javax.swing.JToolBar();
        btnWebQQ = new javax.swing.JButton();
        btnQZone = new javax.swing.JButton();
        btnWeiBo = new javax.swing.JButton();
        btnMail = new javax.swing.JButton();
        btnVIP = new javax.swing.JButton();
        jButton6 = new javax.swing.JButton();
        jButton7 = new javax.swing.JButton();
        face = new javax.swing.JButton();
        lblNickname = new javax.swing.JLabel();
        comboStatus = new javax.swing.JComboBox();
        jLabel3 = new javax.swing.JLabel();
        lblLnick = new javax.swing.JLabel();
        containerPanel = new javax.swing.JPanel();
        tabbedPane = new javax.swing.JTabbedPane();
        contactsPanel = new javax.swing.JPanel();
        groupPanel = new javax.swing.JPanel();
        recentPanel = new javax.swing.JPanel();
        bottomPanel = new javax.swing.JPanel();
        messageToolBar = new javax.swing.JToolBar();
        btnNewMessage = new javax.swing.JButton();
        jSeparator1 = new javax.swing.JToolBar.Separator();

        dialogMemberInfo.setTitle("个人资料");
        dialogMemberInfo.setBounds(new java.awt.Rectangle(400, 80, 560, 640));

        btnFace.setIcon(new javax.swing.ImageIcon(getClass().getResource("/iqq/res/images/face.png"))); // NOI18N

        labLevel.setText("距升级到18级还有20天");

        jLabel2.setText("个性签名: ");

        jTabbedPane2.setTabLayoutPolicy(javax.swing.JTabbedPane.SCROLL_TAB_LAYOUT);

        jPanel1.setPreferredSize(new java.awt.Dimension(0, 0));

        jLabel5.setText("性别:");

        jLabel6.setText("生肖:");

        jLabel7.setText("血型:");

        jLabel8.setText("星座:");

        comboGender.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "-", "男", "女" }));

        comboChineseZodiac.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "-", "鼠", "牛", "虎", "兔", "龙", "蛇", "马", "羊", "猴", "鸡", "狗", "猪" }));

        comboBlood.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "-", "A型", "B型", "O型", "AB型", "其它" }));

        comboConstel.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "-", "水瓶座", "双鱼座", "白羊座", "金牛座", "双子座", "巨蟹座", "狮子座", "处女座", "天秤座", "天蝎座", "射手座", "摩羯座" }));

        jLabel9.setText("生日:");

        jLabel10.setText("手机:");

        jLabel11.setText("电话:");

        jLabel12.setText("国家/地区:");

        jLabel13.setText("城市:");

        jLabel14.setText("省份:");

        jLabel15.setText("邮箱:");

        jLabel16.setText("职业:");

        textOccupation.setText("-");

        jLabel17.setText("毕业院校:");

        jLabel18.setText("个人主页:");

        jLabel19.setText("个人说明:");

        textPersonal.setColumns(20);
        textPersonal.setRows(5);
        jScrollPane3.setViewportView(textPersonal);

        jButton9.setText("应用");

        jButton10.setText("取消");

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addComponent(jLabel19)
                        .addContainerGap())
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(jScrollPane3, javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(jPanel1Layout.createSequentialGroup()
                                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                                        .addComponent(textEmail, javax.swing.GroupLayout.Alignment.LEADING)
                                        .addComponent(textCountry, javax.swing.GroupLayout.Alignment.LEADING)
                                        .addComponent(dateChooserBirthday, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                        .addGroup(jPanel1Layout.createSequentialGroup()
                                            .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                                .addComponent(comboGender, javax.swing.GroupLayout.PREFERRED_SIZE, 103, javax.swing.GroupLayout.PREFERRED_SIZE)
                                                .addComponent(jLabel5))
                                            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 37, Short.MAX_VALUE)
                                            .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                                .addComponent(jLabel6)
                                                .addComponent(comboChineseZodiac, javax.swing.GroupLayout.PREFERRED_SIZE, 103, javax.swing.GroupLayout.PREFERRED_SIZE)))
                                        .addComponent(textCollege, javax.swing.GroupLayout.Alignment.LEADING))
                                    .addComponent(jLabel9)
                                    .addComponent(jLabel12)
                                    .addComponent(jLabel15)
                                    .addComponent(jLabel17))
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 13, Short.MAX_VALUE)
                                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                                    .addGroup(jPanel1Layout.createSequentialGroup()
                                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                                            .addComponent(jLabel7)
                                            .addComponent(comboBlood, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                            .addComponent(jLabel10)
                                            .addComponent(textMobile)
                                            .addComponent(jLabel13)
                                            .addComponent(textCity, javax.swing.GroupLayout.PREFERRED_SIZE, 103, javax.swing.GroupLayout.PREFERRED_SIZE)
                                            .addComponent(jLabel16)
                                            .addComponent(jLabel18))
                                        .addGap(35, 35, 35)
                                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                                            .addComponent(jLabel14)
                                            .addComponent(textProvince)
                                            .addComponent(jLabel8)
                                            .addComponent(comboConstel, 0, 104, Short.MAX_VALUE)
                                            .addComponent(jLabel11)
                                            .addComponent(textPhone)))
                                    .addComponent(textOccupation)
                                    .addComponent(textHomepage, javax.swing.GroupLayout.PREFERRED_SIZE, 242, javax.swing.GroupLayout.PREFERRED_SIZE))))
                        .addGap(23, 23, 23))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                        .addGap(0, 0, Short.MAX_VALUE)
                        .addComponent(jButton10, javax.swing.GroupLayout.PREFERRED_SIZE, 71, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(62, 62, 62)
                        .addComponent(jButton9, javax.swing.GroupLayout.PREFERRED_SIZE, 71, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(45, 45, 45))))
        );
        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addGap(36, 36, 36)
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
                            .addComponent(comboConstel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(comboBlood, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(comboChineseZodiac, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(comboGender, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
                            .addComponent(jLabel10)
                            .addComponent(jLabel11)
                            .addComponent(jLabel9))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
                            .addComponent(textPhone, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(textMobile, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(dateChooserBirthday, javax.swing.GroupLayout.PREFERRED_SIZE, 30, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
                            .addComponent(jLabel13)
                            .addComponent(jLabel14)
                            .addComponent(jLabel12))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
                            .addComponent(textCountry, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(textCity, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(textProvince, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
                            .addComponent(jLabel16)
                            .addComponent(jLabel15))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
                            .addComponent(textEmail, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(textOccupation, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
                            .addComponent(jLabel18)
                            .addComponent(jLabel17))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
                            .addComponent(textHomepage, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(textCollege, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(jPanel1Layout.createSequentialGroup()
                                .addGap(24, 24, 24)
                                .addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, 68, javax.swing.GroupLayout.PREFERRED_SIZE))
                            .addComponent(jLabel19)))
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addContainerGap()
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.CENTER)
                            .addComponent(jLabel7)
                            .addComponent(jLabel8)
                            .addComponent(jLabel6)
                            .addComponent(jLabel5))))
                .addGap(18, 18, 18)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jButton9)
                    .addComponent(jButton10))
                .addContainerGap(48, Short.MAX_VALUE))
        );

        jTabbedPane2.addTab("基本资料", jPanel1);

        jLabel20.setText("昵称:");

        javax.swing.GroupLayout dialogMemberInfoLayout = new javax.swing.GroupLayout(dialogMemberInfo.getContentPane());
        dialogMemberInfo.getContentPane().setLayout(dialogMemberInfoLayout);
        dialogMemberInfoLayout.setHorizontalGroup(
            dialogMemberInfoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(dialogMemberInfoLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(btnFace)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(dialogMemberInfoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(dialogMemberInfoLayout.createSequentialGroup()
                        .addComponent(jLabel20)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(textNickname, javax.swing.GroupLayout.PREFERRED_SIZE, 88, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(42, 42, 42)
                        .addComponent(labLevel))
                    .addGroup(dialogMemberInfoLayout.createSequentialGroup()
                        .addComponent(jLabel2)
                        .addGap(2, 2, 2)
                        .addComponent(textLnick, javax.swing.GroupLayout.PREFERRED_SIZE, 358, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap(43, Short.MAX_VALUE))
            .addComponent(jTabbedPane2, javax.swing.GroupLayout.Alignment.TRAILING)
        );
        dialogMemberInfoLayout.setVerticalGroup(
            dialogMemberInfoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(dialogMemberInfoLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(dialogMemberInfoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(dialogMemberInfoLayout.createSequentialGroup()
                        .addGroup(dialogMemberInfoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(textNickname, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(labLevel)
                            .addComponent(jLabel20))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addGroup(dialogMemberInfoLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jLabel2)
                            .addComponent(textLnick, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                    .addComponent(btnFace))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jTabbedPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 554, Short.MAX_VALUE))
        );

        setOpaque(false);
        setPreferredSize(new java.awt.Dimension(255, 555));
        setLayout(new java.awt.BorderLayout());

        QQToolBar.setBackground(new java.awt.Color(240, 242, 242));
        QQToolBar.setFloatable(false);
        QQToolBar.setRollover(true);
        QQToolBar.setOpaque(false);

        btnWebQQ.setIcon(new javax.swing.ImageIcon(getClass().getResource("/iqq/res/images/icon/webqq.gif"))); // NOI18N
        btnWebQQ.setFocusable(false);
        btnWebQQ.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        btnWebQQ.setPreferredSize(new java.awt.Dimension(24, 24));
        btnWebQQ.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        btnWebQQ.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnWebQQActionPerformed(evt);
            }
        });
        QQToolBar.add(btnWebQQ);

        btnQZone.setIcon(new javax.swing.ImageIcon(getClass().getResource("/iqq/res/images/icon/qzone.gif"))); // NOI18N
        btnQZone.setFocusable(false);
        btnQZone.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        btnQZone.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        btnQZone.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnQZoneActionPerformed(evt);
            }
        });
        QQToolBar.add(btnQZone);

        btnWeiBo.setIcon(new javax.swing.ImageIcon(getClass().getResource("/iqq/res/images/icon/t.gif"))); // NOI18N
        btnWeiBo.setFocusable(false);
        btnWeiBo.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        btnWeiBo.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        btnWeiBo.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnWeiBoActionPerformed(evt);
            }
        });
        QQToolBar.add(btnWeiBo);

        btnMail.setIcon(new javax.swing.ImageIcon(getClass().getResource("/iqq/res/images/icon/email.gif"))); // NOI18N
        btnMail.setFocusable(false);
        btnMail.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        btnMail.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        btnMail.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnMailActionPerformed(evt);
            }
        });
        QQToolBar.add(btnMail);

        btnVIP.setIcon(new javax.swing.ImageIcon(getClass().getResource("/iqq/res/images/icon/vip.gif"))); // NOI18N
        btnVIP.setFocusable(false);
        btnVIP.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        btnVIP.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        btnVIP.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnVIPActionPerformed(evt);
            }
        });
        QQToolBar.add(btnVIP);

        jButton6.setIcon(new javax.swing.ImageIcon(getClass().getResource("/iqq/res/images/icon/v.gif"))); // NOI18N
        jButton6.setFocusable(false);
        jButton6.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jButton6.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        QQToolBar.add(jButton6);

        jButton7.setIcon(new javax.swing.ImageIcon(getClass().getResource("/iqq/res/images/icon/weixin.gif"))); // NOI18N
        jButton7.setFocusable(false);
        jButton7.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jButton7.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        QQToolBar.add(jButton7);

        face.setIcon(new javax.swing.ImageIcon(getClass().getResource("/iqq/res/images/face.png"))); // NOI18N
        face.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                faceActionPerformed(evt);
            }
        });

        lblNickname.setText("承∮诺");

        comboStatus.setFont(new java.awt.Font("AR PL UMing CN", 0, 14)); // NOI18N
        comboStatus.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "在线", "Q我吧", "忙碌", "隐身", "离开", "请勿扰" }));
        comboStatus.setBorder(null);
        comboStatus.setFocusable(false);
        comboStatus.setOpaque(false);
        comboStatus.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) {
                comboStatusItemStateChanged(evt);
            }
        });

        jLabel3.setText("签名:");

        lblLnick.setText("我想把文本框和下拉列表框的背景设置为透明");

        javax.swing.GroupLayout topPanelLayout = new javax.swing.GroupLayout(topPanel);
        topPanel.setLayout(topPanelLayout);
        topPanelLayout.setHorizontalGroup(
            topPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(topPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(topPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(QQToolBar, javax.swing.GroupLayout.DEFAULT_SIZE, 235, Short.MAX_VALUE)
                    .addGroup(topPanelLayout.createSequentialGroup()
                        .addComponent(face)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(topPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(topPanelLayout.createSequentialGroup()
                                .addComponent(lblNickname)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(comboStatus, javax.swing.GroupLayout.PREFERRED_SIZE, 63, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addGap(0, 0, Short.MAX_VALUE))
                            .addGroup(topPanelLayout.createSequentialGroup()
                                .addComponent(jLabel3)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(lblLnick, javax.swing.GroupLayout.PREFERRED_SIZE, 136, Short.MAX_VALUE)))))
                .addContainerGap())
        );
        topPanelLayout.setVerticalGroup(
            topPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(topPanelLayout.createSequentialGroup()
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(topPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(face)
                    .addGroup(topPanelLayout.createSequentialGroup()
                        .addGroup(topPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(comboStatus, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(lblNickname))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addGroup(topPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jLabel3)
                            .addComponent(lblLnick, javax.swing.GroupLayout.PREFERRED_SIZE, 18, javax.swing.GroupLayout.PREFERRED_SIZE))))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(QQToolBar, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE))
        );

        add(topPanel, java.awt.BorderLayout.PAGE_START);

        containerPanel.setLayout(new java.awt.BorderLayout());

        tabbedPane.setPreferredSize(new java.awt.Dimension(96, 260));
        tabbedPane.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                tabbedPaneMouseClicked(evt);
            }
            public void mouseExited(java.awt.event.MouseEvent evt) {
                tabbedPaneMouseExited(evt);
            }
        });
        tabbedPane.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusLost(java.awt.event.FocusEvent evt) {
                tabbedPaneFocusLost(evt);
            }
        });

        contactsPanel.setBorder(null);
        contactsPanel.setAutoscrolls(true);
        contactsPanel.setLayout(new java.awt.BorderLayout());
        tabbedPane.addTab("联系人", contactsPanel);

        groupPanel.setLayout(new java.awt.BorderLayout());
        tabbedPane.addTab("群/讨论组", groupPanel);

        recentPanel.setLayout(new java.awt.BorderLayout());
        tabbedPane.addTab("最近联系人", recentPanel);

        containerPanel.add(tabbedPane, java.awt.BorderLayout.CENTER);

        add(containerPanel, java.awt.BorderLayout.CENTER);

        bottomPanel.setLayout(new java.awt.BorderLayout());

        messageToolBar.setRollover(true);
        messageToolBar.setAutoscrolls(true);
        messageToolBar.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
        messageToolBar.setDebugGraphicsOptions(javax.swing.DebugGraphics.NONE_OPTION);

        btnNewMessage.setIcon(new javax.swing.ImageIcon(getClass().getResource("/iqq/res/images/icon/minilogo.png"))); // NOI18N
        btnNewMessage.setToolTipText("菜单");
        btnNewMessage.setFocusable(false);
        btnNewMessage.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        btnNewMessage.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        messageToolBar.add(btnNewMessage);
        messageToolBar.add(jSeparator1);

        bottomPanel.add(messageToolBar, java.awt.BorderLayout.CENTER);

        add(bottomPanel, java.awt.BorderLayout.PAGE_END);
    }// </editor-fold>//GEN-END:initComponents

    private void faceActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_faceActionPerformed
        // TODO add your handling code here:
        this.dialogMemberInfo.setVisible(true);
        try {
            this.btnFace.setIcon(member.getFace());
        } catch (Exception ex) {
            Logger.getLogger(MainPanel.class.getName()).log(Level.SEVERE, null, ex);
        }
        this.textNickname.setText(member.getNickname());
        this.textLnick.setText(member.getLnick());
        this.textMobile.setText(member.getMobile());
        this.textPhone.setText(member.getPhone());
        this.textCountry.setText(member.getCountry());
        this.textCity.setText(member.getCity());
        this.textProvince.setText(member.getProvince());
        this.textEmail.setText(member.getEmail());
        this.textOccupation.setText(member.getOccupation());
        this.textCollege.setText(member.getCollege());
        this.textHomepage.setText(member.getHomepage());
        this.textPersonal.setText(member.getPersonal());
        this.labLevel.setText(member.getLevel());
        String gender = member.getGender();
        if (gender != null && !gender.equals("")) {
            if (gender.equals("male")) {
                this.comboGender.setSelectedIndex(1);
            } else if (gender.equals("female")) {
                this.comboGender.setSelectedIndex(2);
            }
        } else {
            this.comboGender.setSelectedIndex(0);
        }
        
        int chineseZodiac = member.getChineseZodiac();
        for (int i = 0; i <= 12; i++) {
            if (chineseZodiac == i) {
                this.comboChineseZodiac.setSelectedIndex(i);
            }
        }
        
        int blood = member.getBlood();
        for (int i = 0; i <= 12; i++) {
            if (blood == i) {
                this.comboBlood.setSelectedIndex(i);
            }
        }
        
        int constel = member.getConstel();
        for (int i = 0; i <= 12; i++) {
            if (constel == i) {
                this.comboConstel.setSelectedIndex(i);
            }
        }
    }//GEN-LAST:event_faceActionPerformed
    
    private void tabbedPaneMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_tabbedPaneMouseExited
        // TODO add your handling code here:
        if (floatInfo != null) {
            floatInfo.setVisible(false);
        }
    }//GEN-LAST:event_tabbedPaneMouseExited
    
    private void tabbedPaneFocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_tabbedPaneFocusLost
        // TODO add your handling code here:
        if (floatInfo != null) {
            floatInfo.setVisible(false);
        }
    }//GEN-LAST:event_tabbedPaneFocusLost
    
    private void tabbedPaneMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_tabbedPaneMouseClicked
        // TODO add your handling code here:
        JTabbedPane tabbedPane = (JTabbedPane) evt.getSource();
        if (tabbedPane.getSelectedIndex() == 1) {
            this.initGroupTab();
        } else if (tabbedPane.getSelectedIndex() == 2) {
            this.initRecentTab();
        }
        
    }//GEN-LAST:event_tabbedPaneMouseClicked
    
    private void btnWebQQActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnWebQQActionPerformed
        // TODO add your handling code here:
        BrowserUtil.openURL("http://web3.qq.com/");
    }//GEN-LAST:event_btnWebQQActionPerformed
    
    private void btnQZoneActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnQZoneActionPerformed
        // TODO add your handling code here:
        String urlStr = "http://qzone.qq.com/";
        BrowserUtil.openURL(urlStr);
    }//GEN-LAST:event_btnQZoneActionPerformed
    
    private void btnWeiBoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnWeiBoActionPerformed
        // TODO add your handling code here:
        String urlStr = "http://t.qq.com/";
        BrowserUtil.openURL(urlStr);
    }//GEN-LAST:event_btnWeiBoActionPerformed
    
    private void btnMailActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnMailActionPerformed
        // TODO add your handling code here:
        String urlStr = "http://mail.qq.com/";
        BrowserUtil.openURL(urlStr);
    }//GEN-LAST:event_btnMailActionPerformed
    
    private void btnVIPActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnVIPActionPerformed
        // TODO add your handling code here:
        String urlStr = "http://vip.qq.com/";
        BrowserUtil.openURL(urlStr);
    }//GEN-LAST:event_btnVIPActionPerformed
    
    private void comboStatusItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_comboStatusItemStateChanged
        // TODO add your handling code here:
        Runnable r = new Runnable() {
            
            @Override
            public void run() {
                int loginStatusIndex = comboStatus.getSelectedIndex();
                String loginStatus = "online";
                switch (loginStatusIndex) {
                    case 1: {
                        loginStatus = "callme";
                        break;
                    }
                    case 2: {
                        loginStatus = "busy";
                        break;
                    }
                    case 3: {
                        loginStatus = "hidden";
                        break;
                    }
                    case 4: {
                        loginStatus = "away";
                        break;
                    }
                    case 5: {
                        loginStatus = "silent";
                        break;
                    }
                }
                
                MemberService.getInstance().changeStatus(loginStatus);
            }
        };
        
        if (r != null) {
            ThreadUtil.submit(r);
        }
        
    }//GEN-LAST:event_comboStatusItemStateChanged
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JToolBar QQToolBar;
    private javax.swing.JPanel bottomPanel;
    private javax.swing.JButton btnFace;
    private javax.swing.JButton btnMail;
    private javax.swing.JButton btnNewMessage;
    private javax.swing.JButton btnQZone;
    private javax.swing.JButton btnVIP;
    private javax.swing.JButton btnWebQQ;
    private javax.swing.JButton btnWeiBo;
    private javax.swing.JComboBox comboBlood;
    private javax.swing.JComboBox comboChineseZodiac;
    private javax.swing.JComboBox comboConstel;
    private javax.swing.JComboBox comboGender;
    private javax.swing.JComboBox comboStatus;
    private javax.swing.JPanel contactsPanel;
    private javax.swing.JPanel containerPanel;
    private iqq.ui.DateChooser dateChooserBirthday;
    private javax.swing.JDialog dialogMemberInfo;
    private javax.swing.JButton face;
    private javax.swing.JPanel groupPanel;
    private javax.swing.JButton jButton10;
    private javax.swing.JButton jButton6;
    private javax.swing.JButton jButton7;
    private javax.swing.JButton jButton9;
    private javax.swing.JLabel jLabel10;
    private javax.swing.JLabel jLabel11;
    private javax.swing.JLabel jLabel12;
    private javax.swing.JLabel jLabel13;
    private javax.swing.JLabel jLabel14;
    private javax.swing.JLabel jLabel15;
    private javax.swing.JLabel jLabel16;
    private javax.swing.JLabel jLabel17;
    private javax.swing.JLabel jLabel18;
    private javax.swing.JLabel jLabel19;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel20;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JLabel jLabel8;
    private javax.swing.JLabel jLabel9;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JScrollPane jScrollPane3;
    private javax.swing.JToolBar.Separator jSeparator1;
    private javax.swing.JTabbedPane jTabbedPane2;
    private javax.swing.JLabel labLevel;
    private javax.swing.JLabel lblLnick;
    private javax.swing.JLabel lblNickname;
    private javax.swing.JToolBar messageToolBar;
    private javax.swing.JPanel recentPanel;
    private javax.swing.JTabbedPane tabbedPane;
    private javax.swing.JTextField textCity;
    private javax.swing.JTextField textCollege;
    private javax.swing.JTextField textCountry;
    private javax.swing.JTextField textEmail;
    private javax.swing.JTextField textHomepage;
    private javax.swing.JTextField textLnick;
    private javax.swing.JTextField textMobile;
    private javax.swing.JTextField textNickname;
    private javax.swing.JTextField textOccupation;
    private javax.swing.JTextArea textPersonal;
    private javax.swing.JTextField textPhone;
    private javax.swing.JTextField textProvince;
    private javax.swing.JPanel topPanel;
    // End of variables declaration//GEN-END:variables

    void initQQ() throws Exception {
        member = (Member) map.get("member");
        this.face.setIcon(member.getFace());
        this.lblNickname.setText(member.getNickname());
        this.lblLnick.setText(member.getLnick());
        
        String status = member.getStatus();
        //Log.println("********" + status);
        if (status.equals("callme")) {
            this.comboStatus.setSelectedIndex(1);
        } else if (status.equals("away")) {
            this.comboStatus.setSelectedIndex(4);
        } else if (status.equals("busy")) {
            this.comboStatus.setSelectedIndex(2);
        } else if (status.equals("silent")) {
            this.comboStatus.setSelectedIndex(5);
        } else if (status.equals("hidden")) {
            this.comboStatus.setSelectedIndex(3);
        } else {
            this.comboStatus.setSelectedIndex(0);
        }
        
        initQQContacts();
    }
    
    public void initQQContacts() throws Exception {
        categoryList = (List<Category>) map.get("categoryList");
        Log.println("categoryList.size() " + categoryList.size());
        DefaultMutableTreeNode root = new DefaultMutableTreeNode("Friends");
        DefaultMutableTreeNode online = null;
        DefaultMutableTreeNode stranger = new DefaultMutableTreeNode("陌生人");
        DefaultMutableTreeNode blackList = new DefaultMutableTreeNode("黑名单");
        DefaultMutableTreeNode emptyTreeNode = new DefaultMutableTreeNode(" ");
        DefaultMutableTreeNode emptyTreeNode2 = new DefaultMutableTreeNode(" ");
        DefaultMutableTreeNode emptyTreeNode3 = new DefaultMutableTreeNode(" ");
        
        List<Member> onlineFriends = (List<Member>) map.get("onlineFriends");
        if (onlineFriends != null && onlineFriends.size() > 0) {
            online = new DefaultMutableTreeNode("在线好友 [" + onlineFriends.size() + "]");
            for (Member m : onlineFriends) {
                if (m.getNickname().equals("")) {
                    m.setNickname("未知");
                }
                IconTreeNode itn = new IconTreeNode(m);
                online.add(itn);
            }
        } else {
            online = new DefaultMutableTreeNode("在线好友 [0]");
            online.add(emptyTreeNode);
        }
        root.add(online);
        
        if (categoryList != null) {
            for (int i = 0; i < categoryList.size(); i++) {
                Category category = categoryList.get(i);
                category.setIndex(i);
                if (category.getName().equals("")) {
                    category.setName("未知");
                }
                DefaultMutableTreeNode f = new DefaultMutableTreeNode(category.getName() + " [" + categoryList.get(i).getOnlineCount() + "/" + categoryList.get(i).getMemberList().size() + "]");
                
                List<Member> memberList = category.getMemberList();
                for (int j = 0; j < memberList.size(); j++) {
                    Member m = memberList.get(j);
                    if (m.getNickname().equals("")) {
                        m.setNickname("未知");
                    }
                    IconTreeNode itn = new IconTreeNode(m);
                    f.add(itn);
                }
                root.add(f);
            }
        }
        stranger.add(emptyTreeNode2);
        blackList.add(emptyTreeNode3);
        root.add(stranger);
        root.add(blackList);
        
        treeModel = (DefaultTreeModel) map.get("treeModel");
        if (treeModel == null) {
            treeModel = new DefaultTreeModel(root);
        } else {
            treeModel.setRoot(root);
        }
        contactsTree = new JTree(treeModel);
        contactsTree.setRootVisible(true);
        DefaultTreeCellRenderer ceeRender = new MyDefaultTreeCellRenderer();
        contactsTree.setCellRenderer(ceeRender);
        this.contactsPanel.add(new JScrollPane(contactsTree));
        contactsTree.validate();
        contactsPanel.validate();
        mainFrame.validate();
        map.put("treeModel", treeModel);
        Log.println("initContacts");
        
        contactsTree.addMouseListener(new MouseAdapter() {
            
            @Override
            public void mouseClicked(MouseEvent e) {
                JTree tree = (JTree) e.getSource();
                int selRow = tree.getRowForLocation(e.getX(), e.getY());
                TreePath selPath = tree.getPathForLocation(e.getX(), e.getY());
                if (selPath == null || !(selPath.getLastPathComponent() instanceof IconTreeNode)) {
                    return;
                }
                IconTreeNode node = (IconTreeNode) selPath.getLastPathComponent();
                if (e.getClickCount() == 2 && node != null && node.isLeaf()) {
                    //JOptionPane.showMessageDialog(null, "双击成功");
                    //Log.println("mouseClicked!");
                    ChatDialog c = (ChatDialog) map.get("chatDialog");
                    if (c == null) {
                        c = new ChatDialog(mainFrame, false);
                        map.put("chatDialog", c);
                    }
                    try {
                        List<Message> MessageList = StackMessageService.getIntance().pop(node.getMember().getUin());
                        if (MessageList != null && !MessageList.isEmpty()) {
                            for (Message msg : MessageList) {
                                c.addChat(msg);
                            }
                            String key = "messagePrompt" + MessageList.get(0).getMember().getUin();
                            JButton btnPrompt = (JButton) messagePrompt.get(key);
                            if (btnPrompt != null) {
                                messageToolBar.remove(btnPrompt);
                                messageToolBar.validate();
                                messageToolBar.repaint();
                                messagePrompt.remove(key);
                                newMessageFrame.removeButton(key);
                            }
                        } else {
                            Message msg = new Message();
                            msg.setMember(node.getMember());
                            c.addChat(msg);
                        }
                        
                    } catch (Exception ex) {
                        Logger.getLogger(MainPanel.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    c.setVisible(true);
                }
            }
        });
        
        this.contactsTree.addMouseMotionListener(new MouseMotionAdapter() {
            
            private Member member = null;
            
            @Override
            public void mouseMoved(MouseEvent e) {
                int x = (int) e.getPoint().getX();
                int y = (int) e.getPoint().getY();
                TreePath path = contactsTree.getPathForLocation(x, y);
                if (path != null) {
                    Object obj = path.getLastPathComponent();
                    if (obj instanceof IconTreeNode) {
                        IconTreeNode iconTreeNode = (IconTreeNode) obj;
                        member = iconTreeNode.getMember();
                        Runnable r = new Runnable() {
                            
                            @Override
                            public void run() {
                                try {
                                    member.setFace(MemberService.getInstance().downloadFace(member));
                                    if (member.getLevel() == null || member.getLevel().equals("")) {
                                        try {
                                            //下载个人信息
                                            member = MemberService.getInstance().getMemberInfo(member);
                                        } catch (Exception ex) {
                                            Logger.getLogger(MainPanel.class.getName()).log(Level.SEVERE, null, ex);
                                        }
                                    }
                                    //Log.println(member.getFace());
                                } catch (Exception ex) {
                                    Logger.getLogger(MyDefaultTreeCellRenderer.class.getName()).log(Level.SEVERE, null, ex);
                                }
                            }
                        };
                        
                        if (member != null && !member.isIsDownloadInfo()) {
                            ThreadUtil.submit(r);
                        }
                        
                        treeModel.nodeChanged(iconTreeNode);

                        //JOptionPane.showMessageDialog(null, "X>" + x +" y>" + y);
                        //个人信息显示,浮动窗口，定位显示坐标
                        int showX = mainFrame.getX() - 175;
                        int showY = contactsTree.getY() + y + 220;
                        Rectangle rectangle = new Rectangle(showX, showY, 180, 130);
                        if (floatInfo == null) {
                            floatInfo = new FloatInfoDialog(mainFrame, rectangle);
                        } else {
                            floatInfo.setBounds(rectangle);
                        }

                        //设置显示信息
                        floatInfo.lblNickName.setText(member.getNickname());
                        floatInfo.lblMarkname.setText(member.getMarkname());
                        floatInfo.lblGender.setText(member.getGender());
                        floatInfo.lblLnick.setText(member.getLnick());
                        floatInfo.lblLevel.setText(member.getLevel());
                        try {
                            floatInfo.btnFace.setIcon(member.getFace());
                        } catch (Exception ex) {
                            Logger.getLogger(MainPanel.class.getName()).log(Level.SEVERE, null, ex);
                        }
                        floatInfo.setMember(member);
                        floatInfo.setVisible(true);
                    } else {
                        if (floatInfo != null) {
                            floatInfo.setVisible(false);
                        }
                    }
                }
                
            }
        });

        //初始化群
        initGroupTab();

        //监听信息
        MessageService.setIsRun(true);
        ThreadUtil.submit(MessageService.getIntance());
        
        System.gc();
    }
    
    public void initGroupTab() {
        List<Group> grouptList = GroupService.getInstance().downloadGroupList();
        if (grouptList == null || grouptList.isEmpty()) {
            return;
        }
        DefaultMutableTreeNode root = (DefaultMutableTreeNode) map.get("recentNode");
        if (root == null) {
            root = new DefaultMutableTreeNode("Groups");
        }
        IconTreeNode itn = null;
        for (Group g : grouptList) {
            try {
                itn = new IconTreeNode(g);
            } catch (Exception ex) {
                Logger.getLogger(MainPanel.class.getName()).log(Level.SEVERE, null, ex);
            }
            root.add(itn);
        }
        groupTree = (JTree) map.get("groupTreeMap");
        if (groupTree == null) {
            groupTree = new JTree(root);
            map.put("groupTreeMap", groupTree);
        }
        groupTree.setRootVisible(true);
        DefaultTreeCellRenderer ceeRender = new MyDefaultTreeCellRenderer();
        groupTree.setCellRenderer(ceeRender);
        JPanel recent = (JPanel) map.get("groupPanel");
        if (recent == null) {
            this.groupPanel.add(new JScrollPane(groupTree));
            map.put("groupPanel", groupPanel);
        }
        groupTree.validate();
        this.groupPanel.removeAll();
        this.groupPanel.add(new JScrollPane(groupTree));
        
        groupTree.addMouseListener(new MouseAdapter() {
            
            @Override
            public void mouseClicked(MouseEvent e) {
                JTree tree = (JTree) e.getSource();
                int selRow = tree.getRowForLocation(e.getX(), e.getY());
                TreePath selPath = tree.getPathForLocation(e.getX(), e.getY());
                if (selPath == null || !(selPath.getLastPathComponent() instanceof IconTreeNode)) {
                    return;
                }
                IconTreeNode node = (IconTreeNode) selPath.getLastPathComponent();
                if (e.getClickCount() == 2 && node != null && node.isLeaf()) {
                    //JOptionPane.showMessageDialog(null, "双击成功");
                    //Log.println("mouseClicked!");
                    ChatDialog c = (ChatDialog) map.get("chatDialog");
                    if (c == null) {
                        c = new ChatDialog(mainFrame, false);
                        map.put("chatDialog", c);
                    }
                    try {
                        List<Message> MessageList = StackMessageService.getIntance().pop(node.getGroup().getId());
                        if (MessageList != null && !MessageList.isEmpty()) {
                            for (Message msg : MessageList) {
                                c.addChat(msg);
                            }
                            String key = "messagePrompt" + MessageList.get(0).getGroup().getId();
                            JButton btnPrompt = (JButton) messagePrompt.get(key);
                            if (btnPrompt != null) {
                                messageToolBar.remove(btnPrompt);
                                messageToolBar.validate();
                                messageToolBar.repaint();
                                messagePrompt.remove(key);
                            }
                        } else {
                            Message msg = new Message();
                            msg.setGroup(node.getGroup());
                            c.addChat(msg);
                        }
                        
                    } catch (Exception ex) {
                        Logger.getLogger(MainPanel.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    c.setVisible(true);
                }
            }
        });
    }
    
    public void initRecentTab() {
        JLabel loading = new JLabel("加载中...", JLabel.CENTER);
        loading.setIcon(new ImageIcon(Toolkit.getDefaultToolkit().createImage(
                getClass().getResource("/iqq/res/images/icon/flash.gif"))));
        recentPanel.add(loading);
        
        Runnable r = new Runnable() {
            
            @Override
            public void run() {
                List<Member> recentList = CategoryService.getInstance().getRecentList();
                if (recentList == null || recentList.isEmpty()) {
                    return;
                }
                DefaultMutableTreeNode root = (DefaultMutableTreeNode) map.get("recentNode");
                if (root == null) {
                    root = new DefaultMutableTreeNode("Recent");
                }
                IconTreeNode itn = null;
                for (Member m : recentList) {
                    try {
                        itn = new IconTreeNode(m);
                    } catch (Exception ex) {
                        Logger.getLogger(MainPanel.class.getName()).log(Level.SEVERE, null, ex);
                    }
                    root.add(itn);
                }
                recentTree = (JTree) map.get("recentTreeMap");
                if (recentTree == null) {
                    recentTree = new JTree(root);
                    map.put("recentTreeMap", recentTree);
                }
                
                recentTree.setRootVisible(true);
                DefaultTreeCellRenderer ceeRender = new MyDefaultTreeCellRenderer();
                recentTree.setCellRenderer(ceeRender);
                JPanel recent = (JPanel) map.get("recentPanel");
                if (recent == null) {
                    recentPanel.add(new JScrollPane(recentTree));
                    map.put("recentPanel", recentPanel);
                }
                recentTree.validate();
                recentPanel.removeAll();
                recentPanel.add(new JScrollPane(recentTree));
                
                recentTree.addMouseListener(new MouseAdapter() {
                    
                    @Override
                    public void mouseClicked(MouseEvent e) {
                        JTree tree = (JTree) e.getSource();
                        int selRow = tree.getRowForLocation(e.getX(), e.getY());
                        TreePath selPath = tree.getPathForLocation(e.getX(), e.getY());
                        if (selPath == null || !(selPath.getLastPathComponent() instanceof IconTreeNode)) {
                            return;
                        }
                        IconTreeNode node = (IconTreeNode) selPath.getLastPathComponent();
                        if (e.getClickCount() == 2 && node != null && node.isLeaf()) {
                            //JOptionPane.showMessageDialog(null, "双击成功");
                            //Log.println("mouseClicked!");
                            ChatDialog c = (ChatDialog) map.get("chatDialog");
                            if (c == null) {
                                c = new ChatDialog(mainFrame, false);
                                map.put("chatDialog", c);
                            }
                            try {
                                List<Message> MessageList = StackMessageService.getIntance().pop(node.getMember().getUin());
                                if (MessageList != null && !MessageList.isEmpty()) {
                                    for (Message msg : MessageList) {
                                        c.addChat(msg);
                                    }
                                    String key = "messagePrompt" + MessageList.get(0).getMember().getUin();
                                    JButton btnPrompt = (JButton) messagePrompt.get(key);
                                    if (btnPrompt != null) {
                                        messageToolBar.remove(btnPrompt);
                                        messageToolBar.validate();
                                        messageToolBar.repaint();
                                        messagePrompt.remove(key);
                                    }
                                } else {
                                    Message msg = new Message();
                                    msg.setMember(node.getMember());
                                    c.addChat(msg);
                                }
                                
                            } catch (Exception ex) {
                                Logger.getLogger(MainPanel.class.getName()).log(Level.SEVERE, null, ex);
                            }
                            c.setVisible(true);
                        }
                    }
                });
                
                recentTree.addMouseMotionListener(new MouseMotionAdapter() {
                    
                    private Member member = null;
                    
                    @Override
                    public void mouseMoved(MouseEvent e) {
                        int x = (int) e.getPoint().getX();
                        int y = (int) e.getPoint().getY();
                        TreePath path = recentTree.getPathForLocation(x, y);
                        if (path != null) {
                            Object obj = path.getLastPathComponent();
                            if (obj instanceof IconTreeNode) {
                                IconTreeNode iconTreeNode = (IconTreeNode) obj;
                                member = iconTreeNode.getMember();
                                Runnable r = new Runnable() {
                                    
                                    @Override
                                    public void run() {
                                        try {
                                            member.setFace(MemberService.getInstance().downloadFace(member));
                                            if (member.getLevel() == null || member.equals("")) {
                                                try {
                                                    //下载个人信息
                                                    member = MemberService.getInstance().getMemberInfo(member);
                                                } catch (Exception ex) {
                                                    Logger.getLogger(MainPanel.class.getName()).log(Level.SEVERE, null, ex);
                                                }
                                            }
                                            //Log.println(member.getFace());
                                        } catch (Exception ex) {
                                            Logger.getLogger(MyDefaultTreeCellRenderer.class.getName()).log(Level.SEVERE, null, ex);
                                        }
                                    }
                                };
                                
                                if (member != null && !member.isIsDownloadInfo()) {
                                    ThreadUtil.submit(r);
                                }
                                DefaultTreeModel rdtm = (DefaultTreeModel) recentTree.getModel();
                                rdtm.reload();

                                //JOptionPane.showMessageDialog(null, "X>" + x +" y>" + y);
                                //个人信息显示,浮动窗口，定位显示坐标
                                int showX = mainFrame.getX() - 175;
                                int showY = contactsTree.getY() + y + 220;
                                Rectangle rectangle = new Rectangle(showX, showY, 180, 130);
                                if (floatInfo == null) {
                                    floatInfo = new FloatInfoDialog(mainFrame, rectangle);
                                } else {
                                    floatInfo.setBounds(rectangle);
                                }

                                //设置显示信息
                                floatInfo.lblNickName.setText(member.getNickname());
                                floatInfo.lblMarkname.setText(member.getMarkname());
                                floatInfo.lblGender.setText(member.getGender());
                                floatInfo.lblLnick.setText(member.getLnick());
                                floatInfo.lblLevel.setText(member.getLevel());
                                try {
                                    floatInfo.btnFace.setIcon(member.getFace());
                                } catch (Exception ex) {
                                    Logger.getLogger(MainPanel.class.getName()).log(Level.SEVERE, null, ex);
                                }
                                floatInfo.setMember(member);
                                floatInfo.setVisible(true);
                            } else {
                                if (floatInfo != null) {
                                    floatInfo.setVisible(false);
                                }
                            }
                        }
                        
                    }
                });
            }
        };
        if (r != null) {
            ThreadUtil.submit(r);
        }
    }
    
    public synchronized void changeStatus(Category category) throws Exception {
        int index = category.getIndex() + 1;
        //Log.println("index: " + index);
        TreeNode root =
                (TreeNode) treeModel.getRoot();
        //更改状态
        DefaultMutableTreeNode f = (DefaultMutableTreeNode) root.getChildAt(index);
        List<Member> memberList = category.getMemberList();
        f.setUserObject(category.getName() + " [" + category.getOnlineCount() + "/" + memberList.size() + "]");
        f.removeAllChildren();
        for (int j = 0; j < memberList.size(); j++) {
            Member m = memberList.get(j);
            if (m.getNickname().equals("")) {
                m.setNickname("未知");
            }
            IconTreeNode itn = new IconTreeNode(m);
            f.add(itn);
        }
        treeModel.reload(f);
        //treeModel.nodeChanged(f);

        //更新在线列表状态
        root = (TreeNode) treeModel.getRoot();
        DefaultMutableTreeNode online = (DefaultMutableTreeNode) root.getChildAt(0);
        DefaultMutableTreeNode emptyTreeNode = new DefaultMutableTreeNode(" ");
        List<Member> onlineFriends = CategoryService.getInstance().getOnlineFriends();
        //Log.println("********Online : " + onlineFriends.size());
        if (onlineFriends != null && onlineFriends.size() > 0) {
            online.setUserObject("在线好友 [" + onlineFriends.size() + "]");
            online.removeAllChildren();
            for (Member m : onlineFriends) {
                if (m.getNickname().equals("")) {
                    m.setNickname("未知");
                }
                IconTreeNode itn = new IconTreeNode(m);
                online.add(itn);
                //Log.println("addOline:" + m.getAccount());
            }
        } else {
            online.setUserObject("在线好友 [0]");
            online.removeAllChildren();
            online.add(emptyTreeNode);
        }
        
        treeModel.reload(online);
        //treeModel.nodeChanged(online);
    }

    //信息提示
    public void addMessagePrompt(final List<Message> msgList) throws Exception {
        //Log.println("addMessagePrompt");
        if (msgList == null || msgList.isEmpty()) {
            return;
        }

        //信息独立提示条
        Runnable r = new Thread(new Runnable() {
            
            @Override
            public void run() {
                if (newMessageFrame == null) {
                    newMessageFrame = new NewMessageFrame();
                }
                try {
                    newMessageFrame.addMessagePrompt(msgList);
                } catch (Exception ex) {
                    Logger.getLogger(MainPanel.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
        
        ThreadUtil.submit(r);
        
        Message message = msgList.get(0);
        Group group = null;
        long id = -2;
        ImageIcon imageIcon = null;
        String name = null;
        if (message.getMember() != null) {
            member = message.getMember();
            id = member.getUin();
            imageIcon = member.getFace();
            name = member.toString();
        } else if (message.getGroup() != null) {
            group = message.getGroup();
            id = group.getId();
            imageIcon = group.getFace();
            name = group.getName();
        } else {
            return;
        }
        String key = "messagePrompt" + id;
        if (member != null) {
            //download the member infomation and face.
            member.setFace(MemberService.getInstance().downloadFace(member));
            if (member.getStat() <= 0 && member.getClient_type() <= 0) {
                try {
                    //下载个人信息
                    member = MemberService.getInstance().getMemberInfo(member);
                } catch (Exception ex) {
                    Logger.getLogger(MainPanel.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
        
        Icon icon = new ImageIcon(imageIcon.getImage().getScaledInstance(16, 16, imageIcon.getImage().SCALE_DEFAULT));
        JButton btnPrompt = null;
        btnPrompt = (JButton) messagePrompt.get(key);
        if (btnPrompt != null) {
            btnPrompt.setToolTipText(name + ":" + msgList.size() + " 条新信息");
            return;
        } else {
            btnPrompt = new JButton();
            btnPrompt.setToolTipText(1 + " 条新信息");
            btnPrompt.setIcon(icon);
            messagePrompt.put(key, btnPrompt);
        }
        
        this.messageToolBar.add(btnPrompt);
        
        btnPrompt.addActionListener(new ActionListener() {
            
            @Override
            public void actionPerformed(ActionEvent e) {
                //Log.println("btnPrompt clicked!");
                ChatDialog c = (ChatDialog) map.get("chatDialog");
                if (c == null) {
                    c = new ChatDialog(mainFrame, false);
                    map.put("chatDialog", c);
                }
                try {
                    for (Message message : msgList) {
                        Member member = null;
                        Group group = null;
                        long id = -2;
                        if (message.getMember() != null) {
                            member = message.getMember();
                            id = member.getUin();
                        } else if (message.getGroup() != null) {
                            group = message.getGroup();
                            id = group.getId();
                        } else {
                            return;
                        }
                        String key = "messagePrompt" + id;
                        JButton btnPrompt = (JButton) messagePrompt.get(key);
                        if (btnPrompt != null) {
                            messageToolBar.remove(btnPrompt);
                            messageToolBar.validate();
                            messageToolBar.repaint();
                            messagePrompt.remove(key);
                            newMessageFrame.removeButton(key);
                        }
                        
                        c.addChat(message);
                    }
                    
                } catch (Exception ex) {
                    Logger.getLogger(MainPanel.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
        
        newMessage();
    }
    Thread t = null;
    
    private void newMessage() {
        if (t != null) {
            //t.notify();
            return;
        }
        t = new Thread(new Runnable() {
            
            @Override
            public void run() {
                Icon defIcon = new ImageIcon(Toolkit.getDefaultToolkit().createImage(this.getClass().getClassLoader().getResource("iqq/res/images/icon/minilogo.png")));
                Icon flashIcon = new ImageIcon(Toolkit.getDefaultToolkit().createImage(this.getClass().getClassLoader().getResource("iqq/res/images/icon/flash.gif")));
                Icon[] icons = new Icon[]{defIcon, flashIcon};
                
                int current = 0;
                while (true) {
                    if (messagePrompt.isEmpty()) {
                        stopFlash(this);
                        btnNewMessage.setIcon(icons[0]);
                    }
                    btnNewMessage.setIcon(icons[current]);
                    current++;
                    if (current == icons.length) {
                        current = 0;
                    }
                    try {
                        Thread.sleep(600);
                    } catch (InterruptedException ex) {
                        Logger.getLogger(MainPanel.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
                
            }
        });
        
        if (t != null) {
            //t.start();
            t.start();
        }
    }
    
    private synchronized void stopFlash(Runnable r) {
        if (r != null) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ex) {
                Logger.getLogger(MainPanel.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
    
    public void removeButton(String key) {
        JButton btnPrompt = (JButton) messagePrompt.get(key);
        if (btnPrompt != null) {
            messageToolBar.remove(btnPrompt);
            messageToolBar.validate();
            messageToolBar.repaint();
            messagePrompt.remove(key);
        }
    }
}
